////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Filename:    OuttaThisWorldGuts.cpp                                       //
//  Developer:   Ryan Sauls                                                   //
//  Create date: 2/22/2005                                                    //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Description: This is the class implementation for the slot gut of the     //
//               Australian Slot machine called Outta This World.             //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//        Copyright (c) 2005 - Realtime Gaming.  All rights reserved.         //
////////////////////////////////////////////////////////////////////////////////

#include "OuttaThisWorldGuts.h"

static int32 cointoss[2] = {true, false};
static int32 planetNumbers[10] = {0,1,2,3,4,5,6,7,8,9};

////////////////////////////////////////////////////////////////////////////
/// OuttaThisWorldGuts::m_aLineWinSpinResults
///
/// This array is used to quickly get the SpinResult for the number of
/// icons.  It is indexed by wheel icon and then count.  So to get the
/// SpinResult for 5 Space Ships, use the following code snippet:
///
///		SpinResult result = m_aLineWinSpinResults[ ICON_SPACESHIP ][ 5 ];
///
/// In this example result would be set to EVT_FIVE_SPACESHIP.
////////////////////////////////////////////////////////////////////////////
OuttaThisWorldGuts::SpinResult OuttaThisWorldGuts::m_aLineWinSpinResults[NUM_VALID_ICONS][6] = 
{
// Number of icons:		  0				1			2					3						4					5
/* ICON_NINE		*/  { EVT_LOSER,	EVT_LOSER,	EVT_LOSER,			EVT_THREE_NINE,			EVT_FOUR_NINE,		EVT_FIVE_NINE		},
/* ICON_TEN			*/	{ EVT_LOSER,	EVT_LOSER,	EVT_LOSER,			EVT_THREE_TEN,			EVT_FOUR_TEN,		EVT_FIVE_TEN		},
/* ICON_JACK		*/	{ EVT_LOSER,	EVT_LOSER,	EVT_LOSER,			EVT_THREE_JACK,			EVT_FOUR_JACK,		EVT_FIVE_JACK		},
/* ICON_QUEEN		*/	{ EVT_LOSER,	EVT_LOSER,	EVT_LOSER,			EVT_THREE_QUEEN,		EVT_FOUR_QUEEN,		EVT_FIVE_QUEEN		},
/* ICON_KING		*/	{ EVT_LOSER,	EVT_LOSER,	EVT_LOSER,			EVT_THREE_KING,			EVT_FOUR_KING,		EVT_FIVE_KING		},
/* ICON_ACE			*/	{ EVT_LOSER,	EVT_LOSER,	EVT_LOSER,			EVT_THREE_ACE,			EVT_FOUR_ACE,		EVT_FIVE_ACE		},
/* ICON_TELESCOPE	*/	{ EVT_LOSER,	EVT_LOSER,	EVT_TWO_TELESCOPE,	EVT_THREE_TELESCOPE,	EVT_FOUR_TELESCOPE,	EVT_FIVE_TELESCOPE	},
/* ICON_SPACESHIP	*/	{ EVT_LOSER,	EVT_LOSER,	EVT_TWO_SPACESHIP,	EVT_THREE_SPACESHIP,	EVT_FOUR_SPACESHIP,	EVT_FIVE_SPACESHIP	},
/* ICON_RAY_GUN		*/	{ EVT_LOSER,	EVT_LOSER,	EVT_TWO_RAY_GUN,	EVT_THREE_RAY_GUN,		EVT_FOUR_RAY_GUN,	EVT_FIVE_RAY_GUN	},
/* ICON_EARTH		*/	{ EVT_LOSER,	EVT_LOSER,	EVT_TWO_EARTH,		EVT_THREE_EARTH,		EVT_FOUR_EARTH,		EVT_FIVE_EARTH		},
/* ICON_BLACK_HOLE	*/	{ EVT_LOSER,	EVT_LOSER,	EVT_LOSER,			EVT_LOSER,				EVT_LOSER,			EVT_LOSER },
/* ICON_ALIEN		*/	{ EVT_LOSER,	EVT_LOSER,	EVT_LOSER,			EVT_LOSER,				EVT_LOSER,			EVT_LOSER			}
};
        
////////////////////////////////////////////////////////////////////////////
/// OuttaThisWorldGuts::m_aScatterWinSpinResults
///
/// This array is used to quickly get the SpinResult for the number of
/// icons.  It is indexed by icon count only, since Black Holes are the only
/// scatter win.  So to get the SpinResult for 5 Black Holes, use the
/// following code snippet:
///
///		SpinResult result = m_aScatterWinSpinResults[ 5 ];
///
/// In this example result would be set to EVT_FIVE_BLACK_HOLE.
////////////////////////////////////////////////////////////////////////////
OuttaThisWorldGuts::SpinResult OuttaThisWorldGuts::m_aScatterWinSpinResults[6] = 
{
	// ICON_BLACK_HOLE			   Number of Icons
	EVT_LOSER,				// 0
	EVT_SCATTER_NEAR_MISS,	// 1
	EVT_TWO_BLACK_HOLE,		// 2	
	EVT_THREE_BLACK_HOLE,	// 3
	EVT_FOUR_BLACK_HOLE,	// 4
	EVT_FIVE_BLACK_HOLE		// 5
};

int32 OuttaThisWorldGuts::s_aScatterMasks[5] =
{
	SCATTER_REEL_0_MASK,
	SCATTER_REEL_1_MASK,
	SCATTER_REEL_2_MASK,
	SCATTER_REEL_3_MASK,
	SCATTER_REEL_4_MASK
};

////////////////////////////////////////////////////////////////////////////
/// @fn 	 OuttaThisWorldGuts::OuttaThisWorldGuts()   
///
/// This is the default constructor for the class.
////////////////////////////////////////////////////////////////////////////
OuttaThisWorldGuts::OuttaThisWorldGuts()
{
	// If this doesn't compile it means that someone probably added
	// another icon type but did not update the
	// m_aLineWinSpinResults array. 
	C_ASSERT( countof( m_aLineWinSpinResults ) == NUM_VALID_ICONS );

	m_bAllowAlienIconSubstitutions = false;
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 OuttaThisWorldGuts::~OuttaThisWorldGuts()
///
/// Destructor for OuttaThisWorldGuts. 
////////////////////////////////////////////////////////////////////////////
OuttaThisWorldGuts::~OuttaThisWorldGuts()
{
	deallocateAlienSubstitutionIcons();
}

/******************************************************************************
@fn OuttaThisWorldGuts::load

@brief Override of the SlotGuts::load framework function.
       Allocates our map of substitution icons for use in the free game.
******************************************************************************/
bool8 
OuttaThisWorldGuts::load(Info *info)
{
	// do base class load, and take the opportunity now to 
	// load up the substiution icons,
    return super::load( info ) && allocateAlienSubstitionIcons();
}

bool8 OuttaThisWorldGuts::allocateAlienSubstitionIcons()
{
    const SlotReel * pReel = NULL;

    //Go through each reel for both spin modes and
    //make copies of the icons that could get substituted.
    //Change them so they LOOK like aliens
	for( uint8 gamemodeid = 0 ; gamemodeid < NUM_GAME_MODES ; ++gamemodeid )
	{
		// It works out that there are only aliens on reels 0, 2, and 4
		for( uint8 reel = 0 ; reel < getReelCount() ; reel += 2 )
		{
			pReel = getSlotReel( gamemodeid, reel );
			
			for( SlotReel::const_iterator begin( pReel->begin() ), current( pReel->begin() ), end( pReel->end() );
			current != end;
			++current )
			{
				if ( (*current)->iconid == ICON_ALIEN )
				{
					//Map the previous one or two icons to a substitution icon
					if( distance (begin, current) >  1 )
					{
						// Copy & map the previous icon
						SlotReel::const_iterator previous = current - 1;
						
						addSubstitutionIcon( *previous );
						
						// And the previous one, too, if there's one there
						if ( distance( begin, previous ) > 2 )
						{
							addSubstitutionIcon( *--previous );
							
						}
					}
					
					//Map the next one or two icons to a substitution icon
					if ( distance( current, end ) > 1 )
					{                         
						// Copy & map the next icon
						SlotReel::const_iterator next = current + 1;
						
						addSubstitutionIcon( *next );
						
						if( distance( current, end ) > 2 )
						{
							addSubstitutionIcon( *++next );
						}
					}
				}
			}
		}
	}

	return true;
}

void OuttaThisWorldGuts::deallocateAlienSubstitutionIcons()
{	
    //Clean up our substitution map
    for( SlotIconSubstitutionMap::iterator current( m_mapSubstitutionIcons.begin() ), end( m_mapSubstitutionIcons.end() );
            current != end;
            ++current )
            {
                delete current->second;
            }
}

/******************************************************************************
Function name	: OuttaThisWorldGuts::addSubstitutionIcon
@brief	 Adds an icon duplicating the passed icon, except with the iconid
        set to ICON_ALIEN, for use in the getIcon() method.
@return	void  
@param	const SlotIcon* icon - the icon to copy and key against in the new mapping.
******************************************************************************/
void  OuttaThisWorldGuts::addSubstitutionIcon( const SlotIcon* icon)
{
    // Map this icon to a substitution icon
    // Copy the supplied icon
    SlotIcon* subicon = new SlotIcon( *icon );

    // Fix up its iconid
    subicon->iconid = ICON_ALIEN;
    
    // Map it back to the real iterator for later.
    VERIFY( m_mapSubstitutionIcons.insert( make_pair( icon, subicon ) ).second );
}

/******************************************************************************
Function name	: OuttaThisWorldGuts::getIcon
@brief	Returns the SlotIcon for the specified gamemode, reel and position.
        If any icon on the visible reel is an Alien, the
        "real" returned icon is replace with a copy of it having the ICON_ALIEN iconid.
@return	const SlotIcon* - the icon for this gamemode, reel, and position
@param		uint8 gamemodeID
@param		uint8 reelID
@param		uint8 position
******************************************************************************/
const SlotIcon* OuttaThisWorldGuts::getIcon( uint8 gamemodeID, uint8 reelID, uint8 position ) const
{
    const SlotIcon* pRealIcon = super::getIcon( gamemodeID, reelID, position );

    //If this reel has an active crown substitution, then return our mocked up icon
    //that looks like a crown.
    if ( m_bAllowAlienIconSubstitutions
        && ICON_ALIEN != pRealIcon->iconid 
		&& getAlienIconOnReel( reelID ) )
    {
        SlotIconSubstitutionMap::const_iterator substitute = m_mapSubstitutionIcons.find(pRealIcon);

        //If this is a stop than can be substituted with an Alien,
        //return the duplicate Alien icon.
        if( substitute != m_mapSubstitutionIcons.end() )
        {
            return substitute->second;
        }
    }
    return pRealIcon;
}


////////////////////////////////////////////////////////////////////////////
/// @fn 	 OuttaThisWorldGuts::classifyStops()   
///
/// @param   stops      The array of stop positions for the line.
/// @param   bet        The value of the line bet.
/// @param   line       The index of the line.
///
/// @return	 uint8      A payout from the SpinResult enumeration as a uint8.    
///
/// This helper method is used to calculate the payout on a line.
////////////////////////////////////////////////////////////////////////////
void OuttaThisWorldGuts::classifyStops( SpinLine* spinline, uint8* stops, uint8 bet, uint8 line,
	uint8& rtnresult, uint8& multiplier )
{
	// Keep up with whether or not we have a substitution on the rtnresult.
	bool bSubstitution = false;

	// Get The icon we are testing for, which is the first non-alien
	int iconCount = 0;

	uint8 testIcon;

	do
	{
		testIcon = getIcon( getGameModeId(), iconCount, stops[ iconCount ] )->iconid;

		// if it is an alien, and we haven't already noted the substitution
		// do so now...
		if ( !bSubstitution )
		{
			bSubstitution = testIcon == ICON_ALIEN;
		}
	}
	// Break when we've found a non-alien, or increment iconCount to account
	// for the alien we did find...		
	while( testIcon == ICON_ALIEN && ++iconCount < getReelCount() );

	// Now, see how many more of the test icon we have on this payline
	// Loop through the remaining reels until the streak is over
	for ( ++iconCount; iconCount < getReelCount(); ++iconCount )
    {
		// See what this icon is.
		uint8 currentIcon = getIcon( getGameModeId(), iconCount, stops[ iconCount ] )->iconid;

		if ( currentIcon == ICON_ALIEN )
		{
			if ( testIcon == ICON_BLACK_HOLE )
			{
				// alien cannot substitute for black hole so break out of the loop
				break;
			}
			else
			{
				// use alien as a substitution symbol and continue on.
				bSubstitution = true;
				continue;
			}
		}

		// If the current icon is not the test icon...
        if ( currentIcon != testIcon )
        {
			// then the streak is over so break out of the loop
			break;
        }
    }

	// Use the array to look up the spin result for i testIcons.
	rtnresult = lookupLineWinSpinResult( testIcon, iconCount );

	// If we did actually have a substitution and a winning spin...
	if ( bSubstitution && rtnresult != EVT_LOSER )
	{
		// then add a note and change the multiplier.
		spinline->addNote( NOTE_ALIEN_SUBSTITUTION );
	}
}

////////////////////////////////////////////////////////////////////////////
/// @fn		OuttaThisWorldGuts::tryForJackpot()
///
///	This function tries to win the jackpot and adds the scatter if we hit
/// the jackpot.
////////////////////////////////////////////////////////////////////////////
void OuttaThisWorldGuts::tryForJackpot( SlotSpin* spin )
{
	// If we are in the first paid spin (NOT a bonus spin)...
	if ( getGameModeId() == MODE_NORMAL ) 
	{
		// then try for the Random Progressive Jackpot
		// If we hit the jackpot...
		if ( getRandomProgressiveJackpotResult( spin->getSpinLineCount() ) || 
			m_bForceRandomJackpot)
		{
			// then add a jackpot scatter to the spin.
			spin->addScatter( 0,
				getPayout( EVT_RANDOM_PROGRESSIVE_WINNER )->payoutAmount, 1,
				true, EVT_RANDOM_PROGRESSIVE_WINNER, 0 );
		}
    }
}

////////////////////////////////////////////////////////////////////////////
/// @fn		OuttaThisWorldGuts::getScatterWinResult()
///
/// @param   spin				The spin we are evaluating.
/// @param   scatterPositions	An output parameter that contains a bit mask for the icon positions.
///
/// @return	 SpinResult			A payout from the SpinResult enumeration.
///
///	This function looks for scatter wins.  This game supports "left to right" only
////////////////////////////////////////////////////////////////////////////
OuttaThisWorldGuts::SpinResult OuttaThisWorldGuts::getScatterWinResult( SlotSpin* spin, int32& scatterPositions ) const
{
	// Keep up with how many scatter icons we found.
	uint8 numBlackHoleIcons = 0;

	// Loop through each reel.
  	for( int reel = 0; reel < getReelCount(); reel++ )
	{
		// The position bit for the current icon in case it needs to be stored in a mask.
		uint8 position = reel;

		// Loop through each row in the wheel house.
		for( int row = 0; row < 3; row++ )
		{
			// Get the current stop.
			uint8 stop = relativeWheelPosition( getGameModeId(), reel,
				spin->getStops()[ reel ], row );

			// Get the icon for the current stop.
			uint8 currentIcon = getIcon( getGameModeId(), reel, stop )->iconid;
			
			// If the icon is a black hole...
			if ( currentIcon == ICON_BLACK_HOLE )
			{
				// then increase the Ship count
				numBlackHoleIcons++;

				// Set the bit in the position mask for this stop.
				scatterPositions |= 1 << position;
			}

			// Move to the next bit in the position mask.
            position += 5;
		}
	}

	// Use the array to look up the spin result.
	return lookupScatterWinSpinResult( numBlackHoleIcons );
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 OuttaThisWorldGuts::evaluateScatterWin()
///
/// This function determines if the current spin wins a scatter payment and
/// adds the scatter.
////////////////////////////////////////////////////////////////////////////
void OuttaThisWorldGuts::evaluateScatterWin( SlotSpin* spin, SpinResult srScatterResult, int32 scatterPositions )
{
	// If we got the scatter win (or almost got it)
	if ( srScatterResult != EVT_LOSER )
	{
		// Get the base payout for the scatter.
		int32 nPayout = getPayout( srScatterResult )->payoutAmount;
		
		// Scatters payout based on the total bet, so factor in the number of bet lines.
		nPayout *= spin->getSpinLineCount();

		int32 multiplier = 1;

		// During free spin feature there are multipliers applied.
		if ( getGameModeId() == MODE_FREE_SPIN )
		{
			multiplier *= getFeatureGameMultiplier();
		}       

		// Add the payout to the total win for this spin.
		increaseTotalWin( nPayout * multiplier );
    
		// Add a scatter to the spin.
		SlotScatter* pScatter = spin->addScatter( scatterPositions,
			nPayout * getBetPerLine(), multiplier, false, srScatterResult, 0 );

        // In free spin mode, write a note about the variable multiplier.
		if ( getGameModeId() == MODE_FREE_SPIN )
		{
			pScatter->addNote(NOTE_FREE_SPIN_MULTIPLIER);
		}
	}
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 OuttaThisWorldGuts::initializeBonusGame()
///
/// Setup the subgame data to start a new bonus game
////////////////////////////////////////////////////////////////////////////
void OuttaThisWorldGuts::initializeBonusGame( int32 awardedBonusGames )
{
	setFeatureGameMultiplier(MULTIPLIER_FREE_SPIN);
	setBonusPlanetsAwarded( awardedBonusGames );
	initializeAliensFoundCount();
	initializeBonusGameResultIndex();
	initializeCurrentBonusPlanetIndex();
	setBonusPlanetSelectedMask(0);
	for ( int32 nBonusPlanet = 0; nBonusPlanet < MAX_PLANET_PICKS; ++nBonusPlanet )
	{
		setPlanetIDForPick( nBonusPlanet, -1 );
		setBonusPlanetWinType( nBonusPlanet, WIN_TYPE_NONE);
		setBonusPlanetWinAmount( nBonusPlanet, 0 ); 
	}
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 OuttaThisWorldGuts::evaluateFeatureTrigger()
///
/// This function determines if the feature was triggered.
////////////////////////////////////////////////////////////////////////////
void OuttaThisWorldGuts::evaluateFeatureTrigger( SlotSpin* spin, SpinResult srScatterResult, int32 scatterPositions )
{
	// We need a spin result for the feature trigger.
	SpinResult srFeatureTrigger = EVT_LOSER;

	// We need a place to keep up with how many picks to award.
	int32 nBonusPlanetsAwarded = 0;

	// If the scatter result was a loser...
	if ( srScatterResult == EVT_LOSER )
	{
		// then we are done so just return now.
		return;
	}
	
	// Otherwise if the scatter result was a near miss
	if ( srScatterResult == EVT_SCATTER_NEAR_MISS || 
		 srScatterResult == EVT_FEATURE_NEAR_MISS )
	{
		// then we will have a near miss for the feature.
		srFeatureTrigger = EVT_FEATURE_NEAR_MISS;
	}
	// Otherwise...
	// Need Black Holes on reels 1 & 3 (zero-based) To trigger free games
	else if ( lookupScatterIconCount( srScatterResult ) >= 2 )
	{		
		if ( (scatterPositions & s_aScatterMasks[1] ) 
			&& (scatterPositions & s_aScatterMasks[3] ) )
		{
			// We've triggered the feature
			srFeatureTrigger = EVT_OUTTA_THIS_WORLD_FEATURE;
			nBonusPlanetsAwarded = getRandomValueFromProbabilityTable(PT_BONUS_NUMBER_OF_PICKS_VALUE);

			//if(m_bDebugSpinsMode)
			//{
			//	nBonusPlanetsAwarded = Debug_GetPlanetWinCount();
			//}

			DEBUGMSG(( "%d Planet Picks awarded", nBonusPlanetsAwarded ));
		}
	}

	if ( srFeatureTrigger != EVT_LOSER )
	{
		// Add a scatter to the spin for the near miss or the feature trigger.
		spin->addScatter( scatterPositions, 0, 0, false,
			srFeatureTrigger, nBonusPlanetsAwarded );
	}

	initializeBonusGame( nBonusPlanetsAwarded );
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 OuttaThisWorldGuts::classifyScatters( SlotSpin* spin )
///
/// @param   spin       Pointer to the spin with stop data.
///
/// This is an override of the framework method.  
/// It determines if the current spin merits free spins or scatter payments.
////////////////////////////////////////////////////////////////////////////
void OuttaThisWorldGuts::classifyScatters( SlotSpin* spin )
{	
	// Try for the Random Progressive Jackpot
	tryForJackpot( spin );

	// Declare a local variable to track the scatter positions.
	int32 nScatterPositions = 0;

	// See what is the spin result.
	SpinResult spinResult = getScatterWinResult( spin, nScatterPositions );

	// Scatters payout any.
	evaluateScatterWin( spin, spinResult, nScatterPositions );

	// Now see if they triggered the feature.
	evaluateFeatureTrigger( spin, spinResult, nScatterPositions );
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 OuttaThisWorldGuts::getFeatureGameMultiplier() const 
///
/// @return  int32   The multiplier awarded for the feature.
///
/// This is an accessor mutator method to get the multiplier applied to the feature game.
////////////////////////////////////////////////////////////////////////////
int32 
OuttaThisWorldGuts::getFeatureGameMultiplier() const
{
	return m_subGame->getData(SGDIDX_FEATURE_MULTIPLIER);
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 OuttaThisWorldGuts::getGameModeMultiplierAndNoteId( uint8& nGameModeMultiplier, uint8& nNoteId )   
///
/// @param	 nGameModeMultiplier    Returns the new multiplier based on the game mode.
/// @param   nNoteId                Returns the note Id associated with the game mode.
///
/// This helper method is get the game mode note and multiplier.
////////////////////////////////////////////////////////////////////////////
void 
OuttaThisWorldGuts::getGameModeMultiplierAndNoteId( uint8& nGameModeMultiplier, uint8& nNoteId )
{
	// During free spin feature there are multipliers applied.
    if ( getGameModeId() == MODE_FREE_SPIN )
    {
        nNoteId = NOTE_FREE_SPIN_MULTIPLIER;
        nGameModeMultiplier = getFeatureGameMultiplier();
    }
    else
    {
        SlotGuts::getGameModeMultiplierAndNoteId( nGameModeMultiplier, nNoteId );
    }
}
 
////////////////////////////////////////////////////////////////////////////
/// @fn 	 OuttaThisWorldGuts::setFeatureGameMultiplier(int32 nFeatureGameMultiplier) 
///
/// @param   nFeatureGameMultiplier  The multiplier awarded for the feature.
///
/// This is a mutator to set the multiplier applied to the feature game.
////////////////////////////////////////////////////////////////////////////
void 
OuttaThisWorldGuts::setFeatureGameMultiplier(int32 nFeatureGameMultiplier)
{
	m_subGame->update(SGDIDX_FEATURE_MULTIPLIER,nFeatureGameMultiplier);
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 void OuttaThisWorldGuts::setBonusPlanetWinType( int32 nPick, int32 nWinType )
///
/// Accessor for subgame data
////////////////////////////////////////////////////////////////////////////
void  OuttaThisWorldGuts::setBonusPlanetWinType( int32 nPick, int32 nWinType )
{
	ASSERT( nPick >= 0  &&  nPick <= MAX_PLANET_PICKS );

    m_subGame->update( SGDIDX_BONUS_PICK_WIN_TYPE_1 + nPick, nWinType );
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 int32 OuttaThisWorldGuts::getBonusPlanetWinType( int32 nPick ) const
///
/// Accessor for subgame data
////////////////////////////////////////////////////////////////////////////
int32 OuttaThisWorldGuts::getBonusPlanetWinType( int32 nPick ) const
{
	ASSERT( nPick >= 0  &&  nPick <= MAX_PLANET_PICKS );

	// Return the subgame data.
	int32 type = m_subGame->getData( SGDIDX_BONUS_PICK_WIN_TYPE_1 + nPick  );
	if ( type & WIN_INCLUDES_ALIEN )
	{
		return type - WIN_INCLUDES_ALIEN;
	}
	else
	{
		return type;
	}
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 void OuttaThisWorldGuts::setBonusPlanetWinAmount( int32 nPlanet, int32 nAmount )
///
/// Accessor for subgame data
////////////////////////////////////////////////////////////////////////////
void  OuttaThisWorldGuts::setBonusPlanetWinAmount( int32 nPick, int32 nAmount )
{
	ASSERT( nPick >= 0  &&  nPick <= MAX_PLANET_PICKS );

    m_subGame->update( SGDIDX_BONUS_PICK_WIN_AMOUNT_1 + nPick, nAmount );
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 int32 OuttaThisWorldGuts::getBonusPlanetWinAmount( int32 nPlanet ) const
///
/// Accessor for subgame data
////////////////////////////////////////////////////////////////////////////
int32 OuttaThisWorldGuts::getBonusPlanetWinAmount( int32 nPick ) const
{
	ASSERT( nPick >= 0  &&  nPick <= MAX_PLANET_PICKS );

	// Return the subgame data.
	return m_subGame->getData( SGDIDX_BONUS_PICK_WIN_AMOUNT_1 +	nPick );
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 int32 OuttaThisWorldGuts::setPlanetIDForPick( int32 nPick, int32 nPlanet )
///
/// Accessor for subgame data
////////////////////////////////////////////////////////////////////////////
void  OuttaThisWorldGuts::setPlanetIDForPick( int32 nPick, int32 nPlanet )
{
	ASSERT( nPick >= 0  &&  nPick <= MAX_PLANET_PICKS );

    m_subGame->update( SGDIDX_BONUS_PICK_POSITION_1 + nPick , nPlanet );
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 int32 OuttaThisWorldGuts::getBonusPlanetForPick( int32 nPick ) const
///
/// Accessor for subgame data (nPick from 0 to 4)
////////////////////////////////////////////////////////////////////////////
int32 OuttaThisWorldGuts::getBonusPlanetForPick( int32 nPick ) const
{
	ASSERT( nPick >= 0  &&  nPick <= MAX_PLANET_PICKS );

	// Return the subgame data.
	return m_subGame->getData( SGDIDX_BONUS_PICK_POSITION_1 + nPick  );
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 void  OuttaThisWorldGuts::updateBonusPlanetSelectedMask( int32 nPlanet )
///
/// Accessor for subgame data
////////////////////////////////////////////////////////////////////////////
void  OuttaThisWorldGuts::updateBonusPlanetSelectedMask( int32 nPlanet )
{
	ASSERT( nPlanet >= 0 && nPlanet < MAX_PLANET_PICKS );

	int32 nMask = 1 << (1 + nPlanet) ;
	int32 nSelectedMask = getBonusPlanetSelectedMask();
	nSelectedMask |= nMask;
	setBonusPlanetSelectedMask( nSelectedMask );
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 int32 OuttaThisWorldGuts::setBonusPlanetSelectedMask( int32 nMask )
///
/// Accessor for subgame data
////////////////////////////////////////////////////////////////////////////
void  OuttaThisWorldGuts::setBonusPlanetSelectedMask( int32 nMask )
{
    m_subGame->update( SCGIDX_BONUS_PICK_SELECTED_MASK, nMask );
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 int32 OuttaThisWorldGuts::getBonusPlanetSelectedMask() const
///
/// Accessor for subgame data
////////////////////////////////////////////////////////////////////////////
int32 OuttaThisWorldGuts::getBonusPlanetSelectedMask() const
{
	// Return the subgame data.
	return m_subGame->getData( SCGIDX_BONUS_PICK_SELECTED_MASK );
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 int32 OuttaThisWorldGuts::getBonusPlanetsAwarded()
///
/// This helper method is used to get the subgame data that tracks how many
/// planet picks have been awarded.
////////////////////////////////////////////////////////////////////////////
int32 OuttaThisWorldGuts::getBonusPlanetsAwarded() const
{
	// Return the subgame data.
	return m_subGame->getData( SGDIDX_BONUS_PICKS_AWARDED );
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 void OuttaThisWorldGuts::setBonusPlanetsAwarded( int32 nAwarded )
///
/// This helper method is used to initialize the subgame data that tracks
/// which planet pick is currently being processed.
////////////////////////////////////////////////////////////////////////////
void OuttaThisWorldGuts::setBonusPlanetsAwarded( int32 nAwarded )
{
	// Initialize the subgame data to 0.
    m_subGame->update( SGDIDX_BONUS_PICKS_AWARDED, nAwarded );
}


////////////////////////////////////////////////////////////////////////////
/// @fn 	 int32 OuttaThisWorldGuts::getCurrentBonusPlanetIndex()
///
/// This helper method is used to get the subgame data that tracks how many
/// planet picks have been awarded.
////////////////////////////////////////////////////////////////////////////
int32 OuttaThisWorldGuts::getCurrentBonusPlanetIndex() const
{
	// Return the subgame data.
	return m_subGame->getData( SGDIDX_CURRENT_BONUS_PICK_INDEX );
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 void OuttaThisWorldGuts::incrementCurrentBonusPlanetIndex()
///
/// This helper method is used to increment the subgame data that tracks
/// which planet pick is currently being processed.
////////////////////////////////////////////////////////////////////////////
void OuttaThisWorldGuts::incrementCurrentBonusPlanetIndex()
{
	// Get the current value and then add 1.
    m_subGame->update( SGDIDX_CURRENT_BONUS_PICK_INDEX, getCurrentBonusPlanetIndex() + 1 );
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 void OuttaThisWorldGuts::initializeCurrentBonusPlanetIndex()
///
/// This helper method is used to initialize the subgame data that tracks
/// which planet pick is currently being processed.
////////////////////////////////////////////////////////////////////////////
void OuttaThisWorldGuts::initializeCurrentBonusPlanetIndex()
{
	// Initialize the subgame data to 0.
    m_subGame->update( SGDIDX_CURRENT_BONUS_PICK_INDEX, 0 );
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 int32 OuttaThisWorldGuts::getBonusGameResultIndex()
///
/// This helper method is used to get the subgame data that tracks which
/// index to use with addBonusGame
////////////////////////////////////////////////////////////////////////////
int32 OuttaThisWorldGuts::getBonusGameResultIndex() const
{
	// Return the subgame data.
	return m_subGame->getData( SGDIDX_BONUS_GAME_RESULT_INDEX );
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 int32 OuttaThisWorldGuts::postIncrementBonusGameResultIndex()
///
/// This helper method is used to increment the subgame data that tracks
/// which index to use with addBonusGame
////////////////////////////////////////////////////////////////////////////
int32 OuttaThisWorldGuts::postIncrementBonusGameResultIndex()
{
	int32 nBonusGameResultIndex = getBonusGameResultIndex();
    m_subGame->update( SGDIDX_BONUS_GAME_RESULT_INDEX, nBonusGameResultIndex + 1 );
	return nBonusGameResultIndex;
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 void OuttaThisWorldGuts::initializeBonusGameResultIndex()
///
/// This helper method is used to initialize the subgame data that tracks
/// which index to use with addBonusGame
////////////////////////////////////////////////////////////////////////////
void OuttaThisWorldGuts::initializeBonusGameResultIndex()
{
	// Initialize the subgame data to 1.
    m_subGame->update( SGDIDX_BONUS_GAME_RESULT_INDEX, 1 );
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 void OuttaThisWorldGuts::isBonusPlanetSelected( int32 nPlanet ) const
///
/// Has the planet (0-7) already been selected?
////////////////////////////////////////////////////////////////////////////
bool  OuttaThisWorldGuts::isBonusPlanetSelected( int32 nPlanet ) const
{
	ASSERT( nPlanet >= 0 && nPlanet < MAX_PLANET_PICKS );

	int32 nMask = 1 << (1 + nPlanet) ;
	int32 nSelectedMask = getBonusPlanetSelectedMask();
	return ( (nMask & nSelectedMask) != 0 );
}


////////////////////////////////////////////////////////////////////////////
/// @fn 	 int32 OuttaThisWorldGuts::getBonusPlanetsRemaining()
///
/// This helper method is used to get the subgame data that tracks how many
/// planet picks are left to be processed
////////////////////////////////////////////////////////////////////////////
int32 OuttaThisWorldGuts::getBonusPlanetsRemaining() const
{
	int32 nAwarded = getBonusPlanetsAwarded();
	int32 nRemaining = 0;
	if ( nAwarded )
	{
		int32 nIndex = getCurrentBonusPlanetIndex();
		nRemaining = (nAwarded > nIndex) ? nAwarded - nIndex : 0;
	}
	return nRemaining;
}


////////////////////////////////////////////////////////////////////////////
/// @fn 	 OuttaThisWorldGuts::awardFreeSpins()
///
/// The free spin counter cannot be updated until the bonus game is ready
/// to complete; otherwise the loadSavedGame logic can incorrectly
/// interpret a saved game as a 're-spin' since it already has free spins.
////////////////////////////////////////////////////////////////////////////
void
OuttaThisWorldGuts::awardFreeSpins()
{
	int32 nFreeSpins = INITIAL_FREE_GAME_AWARD;

	int32 nMaxPicks = MAX_PLANET_PICKS;

	for( int32 nPick = 0; nPick < nMaxPicks; ++nPick )
	{
		int32 nWinType = getBonusPlanetWinType( nPick );
		if ( nWinType == WIN_TYPE_FREE_GAMES )
		{
			nFreeSpins += WIN_FREE_GAME_AWARD;
		}
	}

	if ( nFreeSpins )
	{
		incrementFreeSpins( nFreeSpins );
		setGameModeId(MODE_FREE_SPIN);
	}
	else if ( getFreeSpins() )
	{
		setGameModeId(MODE_FREE_SPIN);
	}
	else
	{
		setGameModeId( MODE_NORMAL);
	}

	setBonusGameState(BONUS_GAME_NONE);
	setGameCanComplete(true);
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 OuttaThisWorldGuts::processClientData()
///
/// @param   bonusGameType      The current type of bonus game.
/// @param   bonusDataCount     The number of integers passed from the client.
/// @param   bonusData			An array of integers passed from the client.
/// 
/// This is an override of the framework method.
/// 
////////////////////////////////////////////////////////////////////////////
bool8
OuttaThisWorldGuts::processClientData(uint8 bonusGameType, int32 bonusDataCount, int32 *bonusData)
{
	// Start by assuming that we do not need to reply to this message
	bool8 bReply = false;
	
	if ( getBonusGameState() == BONUS_GAME_ACTIVE && bonusGameType == BONUS_GAME_OUTTA_THIS_WORLD)
	{
		if ( bonusDataCount == 1 )
		{
			int32 nPlanet = *bonusData;
			
			if ( nPlanet >= 0 && nPlanet < MAX_PLANET_PICKS )
			{
				if ( getBonusPlanetsRemaining() == 0 )
				{
				}
				else if ( isBonusPlanetSelected( nPlanet ) )
				{
					// Position already selected.  Log it.
				}
				else
				{
					// The state will change, so a reply is required
					bReply = true;
					
					// Record which planet was picked
					int32 nPick = getCurrentBonusPlanetIndex();
					setPlanetIDForPick( nPick, nPlanet );
					updateBonusPlanetSelectedMask( nPlanet );
					
					int32 nMultiplier = 0;
					int32 nWinType = WIN_TYPE_NONE;

					//There are 5 of each type of planet - free game or credits
					//If we've maxed out either category, then we have to choose from the other
					//Otherwise, I figure the odds be 50/50
					bool8 flip = getRandomFromArray( cointoss, 2 );
					if ( getBonusPlanetCreditPrizeCount() == BONUS_GAME_CREDITS_SPOTS 
						|| flip )
					{						
						nWinType = WIN_TYPE_FREE_GAMES;
					}
					else if ( getBonusPlanetFreeGamesPrizeCount() == BONUS_GAME_FREE_GAMES_SPOTS 
						      || !flip)
					{
						nMultiplier = getRandomValueFromProbabilityTable(PT_BONUS_CREDIT_PRIZE_VALUE);
					}	

					//if(m_bDebugSpinsMode)
					//{
					//	Debug_SetWinType(nPick, nWinType, nMultiplier);
					//}

					//Now set the win type based on the value we got back
					switch ( nMultiplier )
					{
						case 0 :	//No extra work to do here...
							break;
							
						case 2:
							nWinType = WIN_TYPE_MULTIPLIER_2;
							break;
							
						case 3:
							nWinType = WIN_TYPE_MULTIPLIER_3;
							break;
							
						case 5:
							nWinType = WIN_TYPE_MULTIPLIER_5;
							break;
							
						case 10:
							nWinType = WIN_TYPE_MULTIPLIER_10;
							break;
							
						case 25:
							nWinType = WIN_TYPE_MULTIPLIER_25;
							break;
							
						case 100:
							nWinType = WIN_TYPE_MULTIPLIER_100;
							break;
							
						default:	
							ASSERT( !"Unknown multplier value retrieved from probability table!" );
					}

					int32 nWinAmount = 0;
					
					// If this line win is a multiplier then record the credits awarded
					if ( nWinType != WIN_TYPE_FREE_GAMES )
					{		
						ASSERT( nMultiplier );
						int32 basepayoutamount = getBetPerLine() * getNumLinesBet();
						int32 totalmultiplier = nMultiplier;
						
						// 2x award during free spins
						if ( getGameModeId() == MODE_FREE_SPIN )
						{
							totalmultiplier *= getFeatureGameMultiplier();
						}
						
						int32 totalbonuspayoutamount = basepayoutamount * totalmultiplier;
						nWinAmount = totalbonuspayoutamount;
						addBonusGame(0, postIncrementBonusGameResultIndex(), basepayoutamount, totalmultiplier, totalbonuspayoutamount, 0);
					}
					else
					{
						addBonusGame(0, postIncrementBonusGameResultIndex(), 0, 0, 0, WIN_FREE_GAME_AWARD);
					}					
					
					//There may also be an alien, under these conditions : 
					//"Randomly" if there have been no aliens selected, and there have been fewer picks made than awarded
					//OR there's only two picks left and none have been shown
					//OR this is the last pick awarded
					int32 remaining = getBonusPlanetsRemaining();
					int32 alienFoundCount = getAliensFoundCount();

					//This is an attempt to vary the occurrence of "early" aliens, which are aliens shown
					//prior to the last two picks.  This has the effect of making it more difficult to force
					//the alien on pick zero, and more likely as you get closer to "number-of-aliens-total minus 2"
					//Basically, we don't want it always come up on the first or next to last planet pick.
					//Since this doesn't REALLY effect game play, we're not worried about it being "completely" random
					bool8 forceEarlyAlien = nPick == getRandomFromArray( planetNumbers + nPick, 
																		 countof(planetNumbers) - nPick );

					//if(m_bDebugSpinsMode)
					//{
					//	if ( Debug_SpecifiedAlienLocations() )
					//	{
					//		forceEarlyAlien = (g_FeatureOutcomes[nPick] & WIN_INCLUDES_ALIEN) == WIN_INCLUDES_ALIEN;
					//	}
					//}
						
					if ( ( remaining > 2 && !alienFoundCount && forceEarlyAlien )
						|| ( remaining == 2 && 1 != alienFoundCount )
						|| remaining == 1 )
					{
						nWinType |= WIN_INCLUDES_ALIEN ;
						incrementAliensFoundCount();
					}

					setBonusPlanetWinType( nPick, nWinType );

					setBonusPlanetWinAmount( nPick, nWinAmount );

					incrementCurrentBonusPlanetIndex();
					
					// if this was the last pick then wrap up the planet pick feature
					if ( getBonusPlanetsRemaining() == 0 )
					{
						awardFreeSpins();

						//reset debug data
						for( int32 index = 0 ; index < countof(g_FeatureOutcomes) ; ++index )
						{
							g_FeatureOutcomes[index] =  WIN_TYPE_NONE;
						}
						g_NextPlanet = 0;
					}
				}
			}
		}
	}

	
	return bReply;
}


////////////////////////////////////////////////////////////////////////////
/// @fn 	 OuttaThisWorldGuts::isValidGuts()   
///
/// @return	 bool8      True if gut is valid.    
///
/// This helper method is used to see if the current gut ID is valid.
////////////////////////////////////////////////////////////////////////////
bool8 OuttaThisWorldGuts::isValidGuts()
{
	// Make sure that the m_aLineWinSpinResults array has an entry for each reel,
	// and an additional entry in case there are 0 icons on the line.
	// Note:  we can't do this in the constructor because we have to call
	// getReelCount.
	ASSERT( countof( m_aLineWinSpinResults[0] ) == getReelCount( MODE_NORMAL ) + 1 );

	// Make sure that the m_aScatterWinSpinResults array has an entry for each reel,
	// and an additional entry in case there are 0 scatter icons.
	ASSERT( countof( m_aScatterWinSpinResults ) == getReelCount( MODE_NORMAL ) + 1 );

	// Now make sure that both game modes have the same number of reels.
	ASSERT( getReelCount( MODE_NORMAL ) == getReelCount( MODE_FREE_SPIN ) );

	// Finally just check to see if the gut is within the right range.
    return ( getGutsId() >= 3000 && getGutsId() < 3500 );
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 OuttaThisWorldGuts::hasSavedGames()   
///
/// This helper method is a framework override that indicates this machine can have saved games.
////////////////////////////////////////////////////////////////////////////
bool8
OuttaThisWorldGuts::hasSavedGames()
{
	return true;
}


bool8 OuttaThisWorldGuts::getAlienIconOnReel( uint8 nReel ) const
{
	if ( nReel == 0 || nReel == 2 || nReel == 4 )
	{
		int32 id = 0;
		switch ( nReel )
		{
		case 0:
			id = SGDIDX_ALIEN_ICON_SUBST_REEL_1;
			break;
		case 2:
			id = SGDIDX_ALIEN_ICON_SUBST_REEL_3;
			break;
		case 4:
			id = SGDIDX_ALIEN_ICON_SUBST_REEL_5;
			break;
		}
		return 1 == m_subGame->getData( id );
	}

	return false;
}

void  OuttaThisWorldGuts::setAlienIconOnReel( uint8 nReel, bool8 substitute )
{
	ASSERT( nReel == 0 || nReel == 2 || nReel == 4 );
	int32 id = 0;
	switch ( nReel )
	{
	case 0:
		id = SGDIDX_ALIEN_ICON_SUBST_REEL_1;
		break;
	case 2:
		id = SGDIDX_ALIEN_ICON_SUBST_REEL_3;
		break;
	case 4:
		id = SGDIDX_ALIEN_ICON_SUBST_REEL_5;
		break;
	}

	m_subGame->update( id, substitute );
}

void  OuttaThisWorldGuts::clearAlienIconSubstitutions()
{
	setAlienIconOnReel(0, false);
	setAlienIconOnReel(2, false);
	setAlienIconOnReel(4, false);
}

void  OuttaThisWorldGuts::initializeAliensFoundCount()
{
	m_subGame->setServerOnly( SGDIDX_BONUS_ALIENS_FOUND, true );
	m_subGame->update( SGDIDX_BONUS_ALIENS_FOUND, 0 );
}

void OuttaThisWorldGuts::incrementAliensFoundCount()
{
	m_subGame->setServerOnly( SGDIDX_BONUS_ALIENS_FOUND, true );
	m_subGame->update( SGDIDX_BONUS_ALIENS_FOUND,
						1 + m_subGame->getData( SGDIDX_BONUS_ALIENS_FOUND ) );
}

int32 OuttaThisWorldGuts::getAliensFoundCount() const
{
	return m_subGame->getData( SGDIDX_BONUS_ALIENS_FOUND );
}

int32 OuttaThisWorldGuts::getBonusPlanetCreditPrizeCount() const
{
	int32 count = 0;

	for( int32 id = SGDIDX_BONUS_PICK_WIN_TYPE_1; id < getCurrentBonusPlanetIndex(); ++id)
	{
		int32 value = m_subGame->getData( id );
		if ( value != WIN_TYPE_FREE_GAMES )
			++count;
	}

	return count;
}

int32 OuttaThisWorldGuts::getBonusPlanetFreeGamesPrizeCount() const
{
	int32 count = 0;

	for( int32 id = SGDIDX_BONUS_PICK_WIN_TYPE_1; id < getCurrentBonusPlanetIndex(); ++id)
	{
		if ( m_subGame->getData( id ) == WIN_TYPE_FREE_GAMES )
			++count;
	}

	return count;
}


//Debugging Data/Functionality

int32 OuttaThisWorldGuts::g_FeatureOutcomes[MAX_PLANET_PICKS] = 
{
	WIN_TYPE_NONE,
	WIN_TYPE_NONE,
	WIN_TYPE_NONE,
	WIN_TYPE_NONE,
	WIN_TYPE_NONE,
	WIN_TYPE_NONE,
	WIN_TYPE_NONE,
	WIN_TYPE_NONE,
	WIN_TYPE_NONE,
	WIN_TYPE_NONE,
};

int32 OuttaThisWorldGuts::g_NextPlanet(0);


////////////////////////////////////////////////////////////////////////////
/// @fn 	 OuttaThisWorldGuts::preSpinClassifyResults( SlotSpin* spin )
///
/// @param   spin       Pointer to the spin with stop data.
///
/// This method is overridden to alter the reel stops for the respin feature.
////////////////////////////////////////////////////////////////////////////
void OuttaThisWorldGuts::preSpinClassifyResults( SlotSpin* spin )
{
	SlotGuts::preSpinClassifyResults(spin);

	// Once we've reached this point, we're certainly in a spin, and we
	// need to expose our alien-icon swapping to the world.
	m_bAllowAlienIconSubstitutions = true;
	
	clearAlienIconSubstitutions();	
		
	// Then we need to look at the stops to see if
	// any are aliens that will override the other stops.
	// Loop through all of the reels.
	int32 gamemode = getGameModeId();
	for ( uint8 reel = 0; reel < getReelCount(); reel++ )
	{
		for ( uint8 row = 0 ; row < 3 ; ++row )
		{
			// Get the current stop.
			uint8 stop = relativeWheelPosition( gamemode, reel,
				spin->getStops()[ reel ], row );
			
			int32 nIcon = super::getIcon( gamemode, reel, stop )->iconid;
			
			// If this has a crown
			if ( nIcon == ICON_ALIEN )
			{
				setAlienIconOnReel( reel, true );
				break;
			}
		}
	}
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 OuttaThisWorldGuts::postSpinClassifyResults( SlotSpin* spin )
///
/// @param   spin       Pointer to the spin with stop data.
///
/// This method is overridden to see if we can complete the game.
////////////////////////////////////////////////////////////////////////////
void OuttaThisWorldGuts::postSpinClassifyResults( SlotSpin* spin )
{
	// If we have not reached the feature cap yet and we have feature rounds...
	if ( !getMaxPayoutAwarded() && getBonusPlanetsRemaining() )
	{
		// The game can't complete until the bonus game is done.
		setGameCanComplete( false );
		setBonusGameState( BONUS_GAME_ACTIVE );
	}
}


void OuttaThisWorldGuts::initDebugFunctionMap()
{
	SlotGuts::initDebugFunctionMap();

	//addDebugStopFunction( EVT_DEBUG_FUNCTION_WIN_RANDOM, 
	//	new DebugStopFunc<OuttaThisWorldGuts>(this, &OuttaThisWorldGuts::DebugFeature_SetNextPlanetWin) );
}


void OuttaThisWorldGuts::DebugFeature_SetNextPlanetWin( int32 data )
{
	ASSERT( g_NextPlanet >= 0 && g_NextPlanet < MAX_PLANET_PICKS );

	g_FeatureOutcomes[g_NextPlanet++] = data;
}

int32 OuttaThisWorldGuts::Debug_GetPlanetWinCount()
{
	int32 count = 0;

	while(count < countof( g_FeatureOutcomes ))
	{
		if ( g_FeatureOutcomes[count] != WIN_TYPE_NONE )

		{
			++count;


		}
		else
		{
			break;
		}
	}

	return count;
}

void OuttaThisWorldGuts::Debug_GetWinType(int32 nPick, int32& nWinType, int32& nMultiplier)
{
	// this causes the user to get a certain set of results
	// from the Aliens that they pick.
	int32 debugWinType = g_FeatureOutcomes[nPick];

	if ( (debugWinType & WIN_INCLUDES_ALIEN) == WIN_INCLUDES_ALIEN )
	{
		debugWinType -= WIN_INCLUDES_ALIEN;
	}

	if ( debugWinType == WIN_TYPE_FREE_GAMES )
	{
		nWinType = debugWinType;
		nMultiplier = 0;
	}
	else
	{
		switch ( debugWinType )
		{
			case WIN_TYPE_MULTIPLIER_2:
				nMultiplier = 2;
				break;
			case WIN_TYPE_MULTIPLIER_3:
				nMultiplier = 3;
				break;
			case WIN_TYPE_MULTIPLIER_5:
				nMultiplier = 5;
				break;
			case WIN_TYPE_MULTIPLIER_10:
				nMultiplier = 10;
				break;
			case WIN_TYPE_MULTIPLIER_25:
				nMultiplier = 25;
				break;
			case WIN_TYPE_MULTIPLIER_100:
				nMultiplier = 100;
				break;
			default:
				ASSERT( !"Invalid WIN_TYPE set for planet!  Using 2x" );
				nMultiplier = 2;
		}
	}	
}

bool8 OuttaThisWorldGuts::Debug_SpecifiedAlienLocations()
{
	int32 count = 0;

	while(count < countof( g_FeatureOutcomes ))
	{
		if ( (g_FeatureOutcomes[count] & WIN_INCLUDES_ALIEN) == WIN_INCLUDES_ALIEN )
		{
			return true;
		}
		++count;
	}
	return false;
}